package com.jy.modules.cims.settle.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.jy.modules.cims.common.CimsConstant;
import com.jy.modules.cims.common.JResult;
import com.jy.modules.cims.common.sysUtils.CollectionsUtils;
import com.jy.modules.cims.common.sysUtils.DateTimeUtils;
import com.jy.modules.cims.common.sysUtils.ExceptionUtils;
import com.jy.modules.cims.common.sysUtils.SearchParamUtil;
import com.jy.modules.cims.contract.service.ContractService;
import com.jy.modules.cims.creditright.service.SettleCreditService;
import com.jy.modules.cims.data.common.dto.TCMmCostPlanDTO;
import com.jy.modules.cims.data.common.dto.TCMmCreditPackageDTO;
import com.jy.modules.cims.data.dto.ContractAllDto;
import com.jy.modules.cims.data.dto.CreditDetailDto;
import com.jy.modules.cims.data.dto.CreditDetailQueryDto;
import com.jy.modules.cims.data.dto.CreditRightDto;
import com.jy.modules.cims.data.dto.DealDto;
import com.jy.modules.cims.data.dto.credit.CreditSettleInfoDto;
import com.jy.modules.cims.deal.service.DealService;
import com.jy.platform.core.message.DataMsg;
import com.jy.platform.core.message.PageParameter;
import com.jy.platform.core.message.PageUtil;
import com.jy.platform.core.message.QueryReqBean;
import com.jy.platform.restservice.exception.AbaboonException;
import com.jy.platform.restservice.web.base.BaseController;

/**
 * 结算债权业务控制层
 */
@Controller
@RequestMapping("/settle")
public class SettleController extends BaseController {
	private static final String JSP_URL = "cims/creditManage/monthSettle/";
	private static final String JSP_URL_LOAN = "cims/loanDealManage/monthSettle/";
	public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";

	/**
	 * 结算债权业务控制层
	 */
	public SettleController() {
	}

	/**
     * 
     */
	@Autowired
	@Qualifier("com.jy.modules.cims.deal.service.DealService")
	public DealService dealService;

	@Autowired
	@Qualifier("com.jy.modules.cims.creditright.service.SettleCreditService")
	private SettleCreditService settleCreditService;

	@Autowired
	@Qualifier("com.jy.modules.cims.contract.service.ContractService")
	private ContractService contractService;

	@Autowired
	@Qualifier("com.jy.modules.cims.contract.service.ContractService")
	private ContractService serviceContract;

	/**
	 * 通过 Controller 请求 跳转 进入至相关 页面
	 */
	@RequestMapping(value = "/prepareExecute/{operate}")
	public ModelAndView execute(@PathVariable("operate") String operate) throws AbaboonException {
		ModelAndView model = new ModelAndView();
		if ("toQueryPage".equals(operate)) {// 跳转至 查询页面
			model.addObject("type", this.getParameterString("type"));
			model.addObject("bizType", CimsConstant.QUOTATYPE_CR);
			model.setViewName(JSP_URL + "queryCredit");
		} else if ("toAdd".equals(operate)) { // 跳转至 新增页面
			String settleType = this.getParameterString("settleType");
			model.addObject("bizType", CimsConstant.QUOTATYPE_CR);
			if (CimsConstant.DEAL_TYPE_MONTH_BACK.equals(settleType)) {
				model.setViewName("cims/creditManage/monthSettle/addMonthSettle");
			} else if (CimsConstant.DEAL_TYPE_CREDIT_SETTLE.equals(settleType)) {
				model.setViewName("cims/creditManage/monthSettle/addCreditSettle");
			}
		} else if ("toUpdate".equals(operate)) {// 跳转至 修改页面
			String dealCode = this.getParameterString("dealCode");
			model = this.queryOneDTO(dealCode);
			model.setViewName("cims/creditManage/monthSettle/addMonthSettle");
		} else if ("toView".equals(operate)) {// 跳转至 查看页面
			String dealCode = this.getParameterString("dealCode");
			String isCreditBuy = this.getParameterString("isCreditBuy");
			String cooperorgCode = this.getParameterString("cooperorgCode");
			String contractCode = this.getParameterString("contractCode");
			String creditPackageName = this.getParameterString("creditPackageName");
			model = this.queryOneDTO(dealCode);
			List<TCMmCreditPackageDTO> list = serviceContract.dealPackages(cooperorgCode, contractCode, creditPackageName);
			model.addObject("packageDto", list == null ? null : list.get(0));
			model.addObject("isCreditBuy", isCreditBuy);
			model.setViewName("cims/creditManage/monthSettle/viewMonthSettle");
		} else if ("toViewCredit".equals(operate)) {// 跳转至 查看页面
			String dealCode = this.getParameterString("dealCode");
			String cooperorgCode = this.getParameterString("cooperorgCode");
			String contractCode = this.getParameterString("contractCode");
			String creditPackageName = this.getParameterString("creditPackageName");
			model = this.queryOneDTO(dealCode);
			List<TCMmCreditPackageDTO> list = serviceContract.dealPackages(cooperorgCode, contractCode, creditPackageName);
			model.addObject("packageDto", list == null ? null : list.get(0));
			model.setViewName("cims/creditManage/monthSettle/viewCreditSettle");
		}

		if ("toQueryPageLoan".equals(operate)) {// 跳转至 查询页面
			model.addObject("type", this.getParameterString("type"));
			model.addObject("bizType", CimsConstant.QUOTATYPE_LOAN);
			model.setViewName(JSP_URL_LOAN + "queryCredit");
		} else if ("toAddLoan".equals(operate)) { // 跳转至 新增页面
			String settleType = this.getParameterString("settleType");
			model.addObject("bizType", CimsConstant.QUOTATYPE_LOAN);
			if (CimsConstant.DEAL_TYPE_LOAN_MONTH_BACK.equals(settleType)) {
				model.setViewName(JSP_URL_LOAN + "addMonthSettle");
			} else if (CimsConstant.DEAL_TYPE_LOAN_CREDIT_SETTLE.equals(settleType)) {
				model.setViewName(JSP_URL_LOAN + "addCreditSettle");
			}
		} else if ("toUpdateLoan".equals(operate)) {// 跳转至 修改页面
			String dealCode = this.getParameterString("dealCode");
			model = this.queryOneDTO(dealCode);
			model.setViewName(JSP_URL_LOAN + "addMonthSettle");
		} else if ("toViewLoan".equals(operate)) {// 跳转至 查看页面
			String dealCode = this.getParameterString("dealCode");
			String cooperorgCode = this.getParameterString("cooperorgCode");
			String contractCode = this.getParameterString("contractCode");
			String creditPackageName = this.getParameterString("creditPackageName");
			model = this.queryOneDTO(dealCode);
			List<TCMmCreditPackageDTO> list = serviceContract.dealPackages(cooperorgCode, contractCode, creditPackageName);
			model.addObject("packageDto", list == null ? null : list.get(0));
			model.setViewName(JSP_URL_LOAN + "viewMonthSettle");
		} else if ("toViewLoanCredit".equals(operate)) {// 跳转至 查看页面
			String dealCode = this.getParameterString("dealCode");
			String cooperorgCode = this.getParameterString("cooperorgCode");
			String contractCode = this.getParameterString("contractCode");
			String creditPackageName = this.getParameterString("creditPackageName");
			model = this.queryOneDTO(dealCode);
			List<TCMmCreditPackageDTO> list = serviceContract.dealPackages(cooperorgCode, contractCode, creditPackageName);
			model.addObject("packageDto", list == null ? null : list.get(0));
			model.setViewName(JSP_URL_LOAN + "viewCreditSettle");
		}

		return model;
	}

	/**
	 * @description 获取结算信息
	 * @param request
	 * @param response
	 * @param dto
	 * @param dataMsg
	 * @return
	 */
	@RequestMapping(value = "/getSettleInfo")
	@ResponseBody
	public DataMsg getSettleInfo(HttpServletRequest request, HttpServletResponse response, CreditDetailQueryDto dto, @ModelAttribute DataMsg dataMsg) {
		try {
			// 设置异常债权类型
			CreditSettleInfoDto creditSettleInfoDto = settleCreditService.statCreditDetailForSettle(dto);
			dataMsg.setData(creditSettleInfoDto);
		} catch (Exception e) {
			dataMsg.failed(e.getMessage());
			logger.error("执行方法：getSettleInfo异常："+ExceptionUtils.getStackTraceAsString(e));
		}

		return dataMsg;
	}

	/**
	 * @description 根据交易流水号查询交易流水信息
	 * @param dealCode
	 *            交易流水号
	 * @return
	 */
	private ModelAndView queryOneDTO(String dealCode) throws AbaboonException {
		ModelAndView model = new ModelAndView();
		try {
			CreditRightDto creditRightDto = null;
			Map<String, Object> searchParams = new HashMap<String, Object>();
			DealDto dealDto = new DealDto();
			dealDto.setDealCode(dealCode);
			searchParams.put("dto", dealDto);
			QueryReqBean params = new QueryReqBean();
			params.setSearchParams(searchParams);
			PageParameter pageInfo = PageUtil.toPageParameter(new DataMsg());
			params.setPageParameter(pageInfo);
			List<DealDto> dealDtoList = dealService.getDealList(params.getSearchParams());

			if (CollectionsUtils.isNotEmpty(dealDtoList)) {
				dealDto = dealDtoList.get(0);
				/* 查询合约信息 */
				ContractAllDto contractAllDto = contractService.getContractAllInfo(dealDto.getContractCode());
				model.addObject("contractAllDto", contractAllDto);
				model.addObject("dealCode", dealDto.getDealCode());

				creditRightDto = dealService.getDealDetailByCreditListByTotal(SearchParamUtil.getSearchParam(dealDto));
			}

			List<TCMmCostPlanDTO> costPlanList = settleCreditService.searchCostPlanByDealCode(dealCode);
			if (CollectionsUtils.isNotEmpty(costPlanList)) {
				TCMmCostPlanDTO costPlanPlanDto = costPlanList.get(0);
				model.addObject("costPlanPlanDto", costPlanPlanDto);
				model.addObject("settleDate", DateTimeUtils.formatDate(costPlanPlanDto.getStartDate(), DEFAULT_DATE_FORMAT));
			} else {
				if (null != dealDtoList.get(0).getSettleDate()) {
					model.addObject("settleDate", DateTimeUtils.formatDate(dealDtoList.get(0).getSettleDate(), DEFAULT_DATE_FORMAT));
				}
			}

			model.addObject("dealDto", dealDtoList == null ? null : dealDtoList.get(0));
			model.addObject("creditRightDto", creditRightDto);

		} catch (Exception e) {
			throw new AbaboonException("执行queryOneDTO异常：", e);
		}
		return model;
	}

	/**
	 * @description 保存月还结算流水
	 * @Title saveMonthSettle
	 * @Description TODO
	 * @param request
	 * @param dto
	 * @param dataMsg
	 * @return DataMsg
	 * @author lixinyao
	 * @date 2015-3-2-下午8:28:51
	 * @update
	 * @throws
	 */
	@RequestMapping(value = "/saveMonthSettle")
	@ResponseBody
	public DataMsg saveMonthSettle(HttpServletRequest request, CreditDetailQueryDto dto, @ModelAttribute DataMsg dataMsg) {
		try {
			dto = (CreditDetailQueryDto) super.initDto(dto);
			List<String> planStatusList = new ArrayList<String>();
			planStatusList.add(dto.getPlanStatus());
			dto.setPlanStatusList(planStatusList);
			String dealCode = settleCreditService.doSettle(dto);

			dataMsg = super.initDataMsg(dataMsg);
			dataMsg.setMsg("保存成功！");
			dataMsg.setData(this.makeJSONData(dealCode));
		} catch (Exception e) {
			dataMsg.failed(e.getMessage());
			logger.error("保存失败：", e);
		}
		return dataMsg;
	}

	/**
	 * @description 根据交易流水号删除月还交易(同时适合删除二次购买)
	 * @param request
	 * @param dto
	 * @param dataMsg
	 * @return
	 */
	@RequestMapping(value = "/doDeleteSettle")
	@ResponseBody
	public DataMsg doDeleteSettle(HttpServletRequest request, @ModelAttribute DataMsg dataMsg) {
		try {
			String dealCodes = this.getParameterString("dealCodes");
			if (StringUtils.hasText(dealCodes)) {
				dataMsg = super.initDataMsg(dataMsg);
				StringBuffer sb = new StringBuffer();
				String[] dealCodesArray = dealCodes.split(",");

				JResult result = null;
				for (String dealCode : dealCodesArray) {
					result = new JResult();
					result.setSuccess(false);
					try {
						result = settleCreditService.doDeleteSettle(dealCode);
					} catch (Exception e) {
						result.setErrMsg(e.getMessage());
						dataMsg.setStatus("no");
					}
					String mesage = "交易流水号【" + dealCode + "】";
					mesage = result.isSuccess() == true ? mesage+"删除成功!" : mesage+"删除失败:"+result.getErrMsg();
					sb.append(mesage).append("\n");
				}
				dataMsg.setMsg(sb.toString());
			}
		} catch (Exception e) {
			dataMsg.setStatus("no");
			dataMsg.failed(e.getMessage());
			logger.error("删除失败！：", ExceptionUtils.getStackTraceAsString(e));
		}
		return dataMsg;
	}

	/**
	 * @description 月还结算和异常结算，新建结算，债权列表展示。
	 * @Title MonthSettle
	 * @Description TODO
	 * @param request
	 * @param dto
	 * @param dataMsg
	 * @return DataMsg
	 * @author lixinyao
	 * @date 2015-3-2-下午8:29:51
	 * @update
	 * @throws
	 */
	@RequestMapping(value = "/queryMonthSettle")
	@ResponseBody
	public DataMsg queryMonthSettle(HttpServletRequest request, CreditDetailQueryDto dto, @ModelAttribute DataMsg dataMsg) {
		try {
			dto = (CreditDetailQueryDto) super.initDto(dto);
			// 设置异常债权类型
			String abnormalSettle = this.getParameterString("abnormalSettle");
			if (abnormalSettle != null && abnormalSettle.length() > 0) {
				String[] types = abnormalSettle.split(",");
				List<String> planStatusList = new ArrayList<String>();
				for (String type : types) {
					planStatusList.add(type);
				}
				dto.setPlanStatusList(planStatusList);
			}
			dataMsg = super.initDataMsg(dataMsg);
			QueryReqBean params = new QueryReqBean();
			params.setSearchParams(SearchParamUtil.getSearchParam(dto));
			PageParameter pageInfo = PageUtil.toPageParameter(dataMsg);
			params.setPageParameter(pageInfo);
			dataMsg.setData(settleCreditService.searchCreditDetailForSettleByPaging(params.getSearchParams()));
			dataMsg.setTotalRows(pageInfo.getTotalCount());
		} catch (Exception e) {
			dataMsg.failed(e.getMessage());
			logger.error("查询失败：", e);
		}
		return dataMsg;
	}

	/**
	 * @description 根据流水号查询债权列表(已经结算)
	 * @param request
	 * @param response
	 * @param result
	 */
	@RequestMapping(value = "/getCreditDetailByDealCode")
	@ResponseBody
	public DataMsg getCreditDetailByDealCode(HttpServletRequest request, DealDto dto, @ModelAttribute DataMsg dataMsg) throws Exception {
		Map<String, Object> searchParams = new HashMap<String, Object>();
		searchParams.put("dto", dto);
		QueryReqBean params = new QueryReqBean();
		params.setSearchParams(searchParams);
		PageParameter pageInfo = PageUtil.toPageParameter(dataMsg);
		params.setPageParameter(pageInfo);
		List<CreditDetailDto> list = settleCreditService.searchCreditDetailForSettleByDealCode(params.getSearchParams());
		dataMsg.setData(list);
		dataMsg.setTotalRows(pageInfo.getTotalCount());

		return dataMsg;
	}
}